import json
from datetime import datetime, timedelta

from flask import request
from flask_admin import AdminIndexView, expose
from sqlalchemy import func

from app.database.models import Statistics, User
from app.server.flask_app import db
from app.server.flask_app.model_views.mixins.AuthMixin import AuthMixin


class HomeView(AuthMixin, AdminIndexView):
    @staticmethod
    def get_chart_data(date_from: datetime = None, period: int = 30) -> dict:
        """
        :param period: number of last days to receive data
        :return: json object
        """

        if not date_from:
            date_from = datetime.now().date() - timedelta(days=period)

        labels = []
        user_registrations = []
        accounts_added = []
        likes = []
        comments = []
        documents = []
        unique = []
        whitepages = []
        dolphin_accs = []
        wlo_accs = []
        messages_distribution = []

        for i in range(1, period + 1):
            current_date = date_from + timedelta(days=i)
            labels.append(current_date.strftime("%Y-%m-%d"))

            registrations_count = (
                db.session.query(User)
                .filter(func.date(User.was_registered) == current_date)
                .count()
            )
            user_registrations.append(registrations_count)
            statistic = (
                db.session.query(Statistics)
                .filter(func.date(Statistics.days) == current_date)
                .first()
            )
            accounts_added.append(statistic.accounts if statistic else 0)
            likes.append(statistic.likes if statistic else 0)
            comments.append(statistic.comments if statistic else 0)
            documents.append(statistic.documents if statistic else 0)
            unique.append(statistic.uniques if statistic else 0)
            whitepages.append(statistic.whitepages if statistic else 0)
            dolphin_accs.append(statistic.dolphin_accs if statistic else 0)
            wlo_accs.append(statistic.wlo_accs if statistic else 0)
            messages_distribution.append(
                statistic.messages_distribution if statistic is not None else 0
            )

        data = json.dumps(
            {
                "period": period,
                "labels": labels,
                "registrationsCount": user_registrations,
                "accounts_added": accounts_added,
                "likes": likes,
                "comments": comments,
                "documents": documents,
                "unique": unique,
                "whitepages": whitepages,
                "dolphin_accs": dolphin_accs,
                "wlo_accs": wlo_accs,
                "messages_distribution": messages_distribution,
            }
        )

        return data

    @expose("/", methods=["GET", "POST"])
    def index(self):
        if request.method == "POST":
            try:
                date_from = datetime.strptime(request.form.get("date_from"), "%Y-%m-%d")
                date_to = datetime.strptime(request.form.get("date_to"), "%Y-%m-%d")
                period = abs(date_to - date_from).days
                data = self.get_chart_data(date_from, period)
                return data
            except ValueError:
                return ("", 204)
        else:
            data = self.get_chart_data()
            return self.render(
                "admin_panel/home.html",
                chart_data=data,
            )
